package wwl.lsf.hellospringboot.test.多线程题;

import java.util.concurrent.Semaphore;
import java.util.function.IntConsumer;

class ZeroEvenOdd {

  private int n;

  public ZeroEvenOdd(int n) {
    this.n = n;
  }

  private Semaphore zero = new Semaphore(1);
  private Semaphore ji = new Semaphore(0);
  private Semaphore ou = new Semaphore(0);

  // printNumber.accept(x) outputs "x", where x is an integer.
  public void zero(IntConsumer printNumber) throws InterruptedException {
    for (int i = 1; i <= n; i++) {
      zero.acquire();
      printNumber.accept(0);
      if (i % 2 == 0) {
        ou.release();
      } else {
        ji.release();
      }
    }
  }

  public void even(IntConsumer printNumber) throws InterruptedException {
    for (int i = 1; i <= n; i += 2) {
      ji.acquire();
      printNumber.accept(i);
      zero.release();
    }
  }

  public void odd(IntConsumer printNumber) throws InterruptedException {
    for (int i = 2; i <= n; i += 2) {
      ou.acquire();
      printNumber.accept(i);
      zero.release();
    }
  }

  public static void main(String[] args) {
    ZeroEvenOdd zeroEvenOdd = new ZeroEvenOdd(50);
    Thread t1 = new Thread(() -> {
      try {
        zeroEvenOdd.zero((i) -> {
          System.err.print(i);
        });
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });
    t1.start();
    Thread t2 = new Thread(() -> {
      try {
        zeroEvenOdd.even((i) -> {
          System.out.print(i);
        });
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });
    Thread t3 = new Thread(() -> {
      try {
        zeroEvenOdd.odd((i) -> {
          System.out.print(i);
        });
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });
    t3.start();
    t2.start();

  }
}

